package org.aceor.mddal.gateway;

import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.google.common.base.Preconditions;
import org.aceor.mddal.common.sqlparser.result.SQLParsedResult;
import org.aceor.mddal.config.sharding.LogicTable;
import org.aceor.mddal.gateway.executor.ExecuteContext;
import org.aceor.mddal.gateway.router.Router;
import org.aceor.mddal.gateway.sqlparser.SQLParserFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.sql.Date;
import java.util.Arrays;
import java.util.List;

import static org.aceor.mddal.common.utils.CommonUtil.print;

/**
 * Created by lxue on 16/4/12.
 */
public class Main {
    Class<?> clazz = Main.class;

    ApplicationContext applicationContext;
    Router router;

    @Before
    public void init() {
        applicationContext = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
        Preconditions.checkNotNull(applicationContext);
        router = Router.getInstance(applicationContext.getBean(LogicTable.class));
        Preconditions.checkNotNull(router);
    }

    @Test
    public void test_sqlParseEngine_parse_result() {
        String sql = "select * from user where user.id between 2 and 12";
        SQLParsedResult result = SQLParserFactory
                .createSQLParserEngine(sql, Arrays.asList(1, 12, 3, 4), router.getAllTableShardingColumnsMapping())
                .parse();
        print(clazz, result);
    }

    @Test
    public void test_router_route_with_number() {
        String sql = "select * from user u where user.age = ? and (user.id IN(1,?,?) or id = 7) and user.id1 >? ";
        List<Object> args = Arrays.asList(6, 12, 3, 4);
        SQLParsedResult result = SQLParserFactory
                .createSQLParserEngine(sql, args, router.getAllTableShardingColumnsMapping())
                .parse();
        print(clazz, result);
        ExecuteContext executeContext = router.route(result, sql, args);
        print(clazz, executeContext.sqlMap);
    }

    @Test
    public void test_router_route_with_date() {
        String sql = "select * from user u where (u.birth > '2012-09-02' and user.birth < '2012-09-12') and id1 >5.5 ";
        List<Object> args = Arrays.asList("1993-11-10", "1994-11-11");
        SQLParsedResult result = SQLParserFactory
                .createSQLParserEngine(sql, args, router.getAllTableShardingColumnsMapping())
                .parse();
        print(clazz, result);
        ExecuteContext executeContext = router.route(result, sql, args);
        print(clazz, executeContext.sqlMap);
    }

    @Test
    public void test_router_route_with_tb_db_same_sharding() {
        String sql = "select * from user u where id IN (?,?,?,?,?,?,?,?) and id1 >5.5 ";
        List<Object> args = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
        SQLParsedResult result = SQLParserFactory
                .createSQLParserEngine(sql, args, router.getAllTableShardingColumnsMapping())
                .parse();
        print(clazz, result);
        ExecuteContext executeContext = router.route(result, sql, args);
        print(clazz, executeContext.sqlMap);
    }

    @Test
    public void test_router_route_with_tb_db_not_same_sharding() {
        String sql = "select * from user u where id IN (?,?,?,?,?,?,?,?) and u.birth between '2012-09-02' and  '2012-09-12' and id1 >5.5 ";
        List<Object> args = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
        SQLParsedResult result = SQLParserFactory
                .createSQLParserEngine(sql, args, router.getAllTableShardingColumnsMapping())
                .parse();
        print(clazz, result);
        ExecuteContext executeContext = router.route(result, sql, args);
        print(clazz, executeContext.sqlMap);
    }

    @Test
    public void test_sql_vistorOutputor_args_auto_setting() {
        StringBuilder sb = new StringBuilder();
        MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb);
        visitor.setParameters(Arrays.asList(1, 2, 3, 4, 5));
        String sql = "select * from user u where user.age = ? and (user.id IN(1,?,?) or id = 7) and user.id1 >? ";
        SQLStatementParser parser = new MySqlStatementParser(sql);
        parser.parseStatement().accept(visitor);
        System.out.println(sb);
    }

    @Test
    public void test_any() {
        System.out.println(Date.valueOf("2013-09-09"));
    }
}
